package com.gmcc.docmanager.download.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnFocusChangeListener;
import android.widget.ImageView;

public class TabBar extends ViewGroup implements OnFocusChangeListener {
	public static final String LOGTAG = "TabBar";

	private int selectedTabIndex = -1;
	private OnTabChangeListener onTabChangeListener = null;

	private Bitmap mDividerDrawable = null;
	private int mDividerColor = 0xff000000;

	private static final int GAP_FLAG_NO = 0;
	private static final int GAP_FLAG_COLOR = 1;
	private static final int GAP_FLAG_IMG = 2;

	private int gapFlag = GAP_FLAG_NO;

	private static final int gapWidth = 1;
	private static final int gapHeight = 66;

	public static final String TAG_DIVIDER = "TAG_DIVIDER";

	private static final int moveDistance = 10;

	public TabBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initTabBar(context);
	}

	public TabBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		initTabBar(context);
	}

	public TabBar(Context context) {
		super(context);
		initTabBar(context);
	}

	private void initTabBar(Context context) {
		// this.setOnFocusChangeListener(this);
		// gestureDetector = new GestureDetector(context, this);
		selectedTabIndex = -1;
		Log.d(LOGTAG, "initTabBar " + this.toString());
	}

	// public void setDivider(Bitmap divider)
	// {
	// this.divider = divider;
	// }

	public void setDividerBitmap(Bitmap mDividerDrawable) {
		gapFlag = GAP_FLAG_IMG;
		this.mDividerDrawable = mDividerDrawable;
		Drawable d = new BitmapDrawable(mDividerDrawable);
		setBackgroundDrawable(d);
	}

	public void setDividerColor(int color) {
		gapFlag = GAP_FLAG_COLOR;
		this.mDividerColor = color;
		setBackgroundColor(color);
	}

	public void setOnTabChangeListener(OnTabChangeListener onTabChangeListener) {
		this.onTabChangeListener = onTabChangeListener;
	}

	private View getDividerView() {
		switch (gapFlag) {
		case GAP_FLAG_NO:
			return null;
		case GAP_FLAG_COLOR:
			Paint paint = new Paint();
			paint.setColor(mDividerColor);

			Bitmap map = Bitmap.createBitmap(gapWidth, gapHeight,
					Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(map);
			canvas.drawRect(0, 0, gapWidth, gapHeight, paint);

			ImageView divider = new ImageView(this.getContext());
			// final MarginLayoutParams lp = new MarginLayoutParams(gapWidth,
			// LayoutParams.FILL_PARENT);
			final MarginLayoutParams lp = new MarginLayoutParams(gapWidth,
					gapHeight);
			lp.setMargins(0, 0, 0, 0);
			divider.setLayoutParams(lp);
			divider.setImageBitmap(map);
			divider.setTag(TAG_DIVIDER);
			return divider;
		case GAP_FLAG_IMG:
			if (mDividerDrawable != null) {
				ImageView dividerImg = new ImageView(this.getContext());
				// final MarginLayoutParams lpImg = new
				// MarginLayoutParams(mDividerDrawable.getWidth(),
				// LayoutParams.FILL_PARENT);
				final MarginLayoutParams lpImg = new MarginLayoutParams(
						mDividerDrawable.getWidth(), mDividerDrawable
								.getHeight());
				lpImg.setMargins(0, 0, 0, 0);
				dividerImg.setLayoutParams(lpImg);
				dividerImg.setBackgroundDrawable(new BitmapDrawable(
						mDividerDrawable));
				dividerImg.setTag(TAG_DIVIDER);
				return dividerImg;
			} else {
				return null;
			}
		}
		return null;
	}

	public void addView(View view) {
		if (view == null) {
			throw new NullPointerException();
		}
		view.setFocusable(true);
		view.setFocusableInTouchMode(true);
		view.setClickable(true);
		view.setOnFocusChangeListener(this);
		if (getTabCount() == 0) {
			View tempView = getDividerView();
			if (tempView != null)
				super.addView(tempView);
		}
		// if (mDividerDrawable != null && getTabCount() == 0)
		// {
		// super.addView(getDividerView());
		// }
		super.addView(view);
		View temp = getDividerView();
		if (temp != null) {
			super.addView(temp);
		}
		// if (mDividerDrawable != null)
		// {
		// super.addView(getDividerView());
		// }
	}

	@Override
	public void removeAllViews() {
		super.removeAllViews();
		selectedTabIndex = -1;
	}

	public void setCurrentTab(int index) {
		// Log.i("TabBar setCurrentTab", "index = " + index +
		// " selectedTabIndex = " + selectedTabIndex);
		if (index < 0 || index >= getChildCount()) {
			return;
		}

		if (selectedTabIndex >= 0) {
			getTabViewAt(selectedTabIndex).setSelected(false);
			getTabViewAt(selectedTabIndex).clearFocus();
		}
		selectedTabIndex = index;
		getTabViewAt(selectedTabIndex).setSelected(true);
		getTabViewAt(selectedTabIndex).requestFocus();

		// hander.sendEmptyMessageDelayed(what, 5000);

	}

	public int getCurrentTabIndex() {
		return this.selectedTabIndex;
	}

	public View getTabViewAt(int index) {
		if (gapFlag == GAP_FLAG_COLOR
				|| (gapFlag == GAP_FLAG_IMG && mDividerDrawable != null)) {
			index = index * 2 + 1;
		}
		return getChildAt(index);
	}

	public void removeTabViewAt(int index) {
		int tmpIndex = index;
		if (gapFlag == GAP_FLAG_COLOR
				|| (gapFlag == GAP_FLAG_IMG && mDividerDrawable != null)) {
			tmpIndex = index * 2 + 1;
			this.removeViewAt(tmpIndex);
			if (0 < tmpIndex - 1 && tmpIndex - 1 < this.getChildCount()) {
				this.removeViewAt(tmpIndex - 1);
			}
		} else {
			this.removeViewAt(index);
		}
		if (index <= selectedTabIndex) {
			selectedTabIndex--;
		}
		this.setCurrentTab(selectedTabIndex);
	}

	public int indexOfTabView(View view) {
		int result = indexOfChild(view);
		if (gapFlag == GAP_FLAG_COLOR
				|| (gapFlag == GAP_FLAG_IMG && mDividerDrawable != null)) {
			result = (result) / 2;
		}
		return result;
	}

	public int getTabCount() {
		int result = getChildCount();

		if (gapFlag == GAP_FLAG_COLOR
				|| (gapFlag == GAP_FLAG_IMG && mDividerDrawable != null)) {
			result = (result) / 2;
		}
		return result;
	}

	// public boolean dispatchKeyEvent(KeyEvent event)
	// {
	// Log.i("KeyEvent", event.toString());
	//
	// boolean result = super.dispatchKeyEvent(event);
	//        
	// return result;
	// }

	// public boolean dispatchTouchEvent(MotionEvent event)
	// {
	// return super.dispatchTouchEvent(event);
	// }

	private int totalWidth = 0;

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		totalWidth = 0;
		final int widthMeasure = MeasureSpec.getSize(widthMeasureSpec);
		final int heightMeasure = MeasureSpec.getSize(heightMeasureSpec);
		// AspLog.d(LOGTAG, "MeasureSpec.getSize: " + widthMeasure + " "+
		// heightMeasure);

		int totalHeight = 0;

		int count = getChildCount();

		for (int i = 0; i < count; ++i) {
			final View child = getChildAt(i);

			if (child == null) {
				continue;
			}

			if (child.getVisibility() == GONE) {
				continue;
			}

			// final MarginLayoutParams lp = ( MarginLayoutParams ) child
			// .getLayoutParams();

			// measureChildWithMargins(child, widthMeasureSpec, 0,
			// heightMeasureSpec, 0);
			measureChild(child, widthMeasureSpec, heightMeasureSpec);

			totalWidth += child.getMeasuredWidth();
			// if (this.divider != null && i != count - 1)
			// {
			// totalWidth += divider.getWidth();
			// }
			// Log.i("totalWidth", "totalWidth=" + totalWidth
			// + " child.getMeasuredWidth="
			// + child.getMeasuredWidth());
			// + lp.leftMargin + lp.rightMargin;

			totalHeight = Math.max(totalHeight, child.getMeasuredHeight());
			// AspLog.e("TabBar","---------------i:"+i);
			// AspLog.e("TabBar",
			// "--------child.getMeasuredHeight():"+child.getMeasuredHeight());
			// AspLog.e("TabBar", "--------totalHeight:"+totalHeight);
		}
		if (totalWidth < widthMeasure) {
			totalWidth = 0;
			count = getTabCount();
			int stepWidth;
			int dividerWidth;
			if (gapFlag == GAP_FLAG_COLOR) {
				dividerWidth = gapWidth * (count + 1);
			} else if (gapFlag == GAP_FLAG_IMG && mDividerDrawable != null) {
				dividerWidth = mDividerDrawable.getWidth() * (count + 1);
			} else {
				dividerWidth = 0;
			}
			stepWidth = (widthMeasure - dividerWidth) / count;
			// Log.i("onMeasure", "" + widthMeasure + " " + stepWidth);
			for (int i = 0; i < count; ++i) {
				final View child = getTabViewAt(i);

				if (child == null) {
					continue;
				}

				if (child.getVisibility() == GONE) {
					continue;
				}

				final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
						stepWidth, MeasureSpec.EXACTLY);
				final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
						child.getMeasuredHeight(), MeasureSpec.EXACTLY);

				child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

				totalWidth += child.getMeasuredWidth();
				// if (gapFlag == GAP_FLAG_COLOR && i != count - 1)
				// {
				// totalWidth += gapWidth;
				// }
				// else if (gapFlag == GAP_FLAG_IMG
				// && this.mDividerDrawable != null && i != count - 1)
				// {
				// totalWidth += mDividerDrawable.getWidth();
				// }
			}
			totalWidth += dividerWidth;
			if (totalWidth < widthMeasure) {
				stepWidth += (widthMeasure - totalWidth);

				View lastTabChild = getTabViewAt(getTabCount() - 1);
				final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
						stepWidth, MeasureSpec.EXACTLY);
				final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
						lastTabChild.getMeasuredHeight(), MeasureSpec.EXACTLY);

				lastTabChild.measure(childWidthMeasureSpec,
						childHeightMeasureSpec);
				totalWidth = widthMeasure;
			}
			super.setMeasuredDimension(widthMeasure, Math.min(totalHeight,
					heightMeasure));
		} else {
			super.setMeasuredDimension(Math.min(totalWidth, widthMeasure), Math
					.min(totalHeight, heightMeasure));
		}
		// AspLog.d(LOGTAG, "onMeasure finished");
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// Log.i("Layout", "" + l + " " + t + " " + r + " " + b);

		int childLeft = 0;
		final int count = getChildCount();

		// Log.i("onLayout: childcount = ", String.valueOf(count));
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != View.GONE) {
				final int childWidth = child.getMeasuredWidth();
				// Log.i("childWidth", "" + childWidth);
				child.layout(childLeft, 0, childLeft + childWidth, child
						.getMeasuredHeight());
				childLeft += childWidth;
				// if (this.divider != null)
				// {
				// childLeft += divider.getWidth();
				// }
			}
		}
		// AspLog.d(LOGTAG, "onLayout finished");
	}

	// @Override
	// public boolean dispatchKeyEvent(KeyEvent event)
	// {
	// scrollMode = 0;
	// return super.dispatchKeyEvent(event);
	// }

	private float touchX;
	private boolean isTouchDown = false;

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		// AspLog.d(LOGTAG, "dispatchTouchEvent: " + ev.toString());
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			touchX = ev.getX();
			isTouchDown = true;
			break;
		case MotionEvent.ACTION_MOVE:
			if (isTouchDown) {
				float dx = touchX - ev.getX();
				// AspLog.d(LOGTAG, "dispatchTouchEvent: ACTION_MOVE " +
				// dx);
				touchX = ev.getX();
				super.scrollBy((int) dx, 0);
				return true;
			}
			break;
		case MotionEvent.ACTION_UP:
		default:
			touchX = ev.getX();
			isTouchDown = false;
			break;
		}
		return super.dispatchTouchEvent(ev);
		// boolean result = super.dispatchTouchEvent(ev);
		// result = gestureDetector.onTouchEvent(ev) || result;
		// return result;
	}

	@Override
	public void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		if (!isTouchDown) {
			final int scrollX = super.getScrollX();
			final int width = super.getWidth();
			final int left = super.getLeft();
			final int right = super.getRight();
			// AspLog.d(LOGTAG, "scrollPos: " + scrollX + " " + width + " "
			// + totalWidth + " " + left + " " + right);
			if (scrollX < 0) {
				super.scrollBy(Math.min(-scrollX, moveDistance), 0);
				invalidate();
				return;
			} else if (scrollX > 0) {
				int dx = totalWidth - scrollX;
				if (dx < width) {
					dx = width - dx;
					super.scrollBy(Math.max(-dx, -moveDistance), 0);
					invalidate();
					return;
				}
			}
			final View child = getFocusedChild();
			if (child == null) {
				return;
			}
			final int childLeft = child.getLeft();
			final int childRight = child.getRight();
			final int absLeft = -scrollX + childLeft;
			final int absRight = -scrollX + childRight;
			// AspLog.d(LOGTAG, "childPos: " + childLeft + " " + childRight +
			// " "
			// + absLeft + " " + absRight);
			if (absLeft < left) {
				super.scrollBy(absLeft - left, 0);
				invalidate();
				return;
			} else if (absRight > right) {
				super.scrollBy(absRight - right, 0);
				invalidate();
				return;
			}
		}
	}

	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		// Log.i("TabBar onFocusChange", "" + v.toString() + " "
		// + String.valueOf(hasFocus));
		if (hasFocus && this.onTabChangeListener != null) {
			int index = indexOfTabView(v);
			// AspLog.d(LOGTAG, "onFocusChange index = " + index);
			if (index != selectedTabIndex) {
				View prevIndView = null;
				if (selectedTabIndex > -1) {
					prevIndView = this.getTabViewAt(selectedTabIndex);
				}
				this.onTabChangeListener.onTabChanged(index, v, prevIndView);
			}
		}
	}
}